﻿using System;
using UnityEngine;
using HWGames.Bundles.Internal.Analytics;
using HWGames.Bundles.Internal.IdfaAuthorization;
using GameAnalyticsSDK;
using GameAnalyticsSDK.Events;
using HWGames.Bundles.Internal.GDPR;

namespace HWGames.Bundles.Internal {
    public class HWSDKBundleBehaviour : MonoBehaviour {
        private const string RoutinesClassPath = "com.hw.installsource.HWInstallSource";
        private const string TAG = "HWSDKBundle";

        private static HWSDKBundleBehaviour _instance;
        private SDKBundleSettings _Settings;
        public HWLogLevel HWLogLevel = HWLogLevel.DEBUG;
        public static bool IsCheckKey { get; private set; } = false;

        private float fps;
        private string fpsText;
        private float frameMS;
        private float curTime = 0;
        private float lastUpdate = 0;
        private GUIStyle gUIStyle = new GUIStyle();
        private Vector2 position = new Vector2(16.0f, 16.0f);
        private float elapsedIntervalTime;
        private int intervalFrameCount;
        private float updateInterval = 0.5f;

        private void Awake() {
            if (transform != transform.root)
                throw new Exception("HWSDKBundle prefab HAS to be at the ROOT level!");

            _Settings = SDKBundleSettings.Load();
            if (_Settings == null)
                throw new Exception("Can't find HWSDKBundle Settings file.");

            if (_instance != null) {
                Destroy(gameObject);
                return;
            }
            _instance = this;
            gameObject.AddComponent<HWCoDelegator>();
            gameObject.AddComponent<HWSDKTime>();
            DontDestroyOnLoad(this);

            gUIStyle.fontSize = 30;
            gUIStyle.fontStyle = FontStyle.Bold;
            gUIStyle.normal.textColor = Color.green;

            //ATT
            if (Tracking.TryIsAdvertisingTracking()) {
                Tracking.TryRequestTracking();
            }
            HWLog.Initialize(HWLogLevel);
            //init sdk
            InitAnalytics();
            InitAdsConsent();
            CheckKey();
        }

        private void InitAnalytics() {
            HWLog.Log("HWSDKBundle", "Initializing Analytics");
            AnalyticsManager.Initialize(_Settings, true);
        }

        private void InitAdsConsent() {
            HWLog.Log("HWSDKBundle", "Initializing GDPR");
            ConsentMgr.Instance.Init();
        }

        public void CheckKey() {
#if UNITY_ANDROID && !UNITY_EDITOR
            try {
                AndroidJavaClass pluginClass = new AndroidJavaClass(RoutinesClassPath);
                string name = pluginClass?.CallStatic<string>("GetPackageInstallerName");
                HWLog.Log(TAG, "Install Source_" + name);
                IsCheckKey = name.Contains("com.android.vending");
            } catch (System.Exception e) {
                if (e != null)
                    Debug.LogError(e);
            }
#else
            IsCheckKey = true;
#endif
            if (IsCheckKey) {
                AnalyticsManager.InstantiateGameAnalytics();
            }
        }

        private void OnApplicationPause(bool pauseStatus) {
            // Brought forward after soft closing 
            if (!pauseStatus) {
                AnalyticsManager.OnApplicationResume();
            }
        }

        private void Update() {
            if (_Settings != null && _Settings.enableFPS) {
                intervalFrameCount++;
                elapsedIntervalTime += Time.unscaledDeltaTime;
                if (elapsedIntervalTime >= updateInterval) {
                    fps = GetIntervalFPS();
                    frameMS = GetIntervalFrameMS();

                    fps = (float)Math.Round(fps, 2);
                    frameMS = (float)Math.Round(frameMS, 2);

                    intervalFrameCount = 0;
                    elapsedIntervalTime = 0.0f;
                    fpsText = GetFPSText();
                }
            }
        }

        private float GetIntervalFPS() {
            return intervalFrameCount / elapsedIntervalTime;
        }

        private float GetIntervalFrameMS() {
            return (elapsedIntervalTime * 1000.0f) / intervalFrameCount;
        }

        private string GetFPSText() {
            return $"FPS: {fps:.00} ({frameMS:.00} ms)";
        }

        private void OnGUI() {
            if (_Settings != null && _Settings.enableFPS) {
                float x = position.x;
                GUI.Label(new Rect(40, 0, 200, 100), fpsText, gUIStyle);
            }
        }
    }
}